using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using UnityEditor;
using UnityEngine;

/// <summary>
/// 协议文档生成器
/// 用于解析 fish_zt_message_protocal_schemas.lua.txt 文件中的协议结构体
/// 输入结构体名称，返回结构体字段的详细说明文档
/// </summary>
public class ProtocolDocGenerator : EditorWindow
{
    private List<string> protocolFilePaths = new List<string>();
    private string currentProtocolPath = "Assets/Res/common_by_u3d/script/Proto/fish_zt_message_protocal_schemas.lua.txt";
    private Vector2 protocolListScrollPos = Vector2.zero;
    private string inputStructName = "";
    private string outputDoc = "";
    private Vector2 scrollPos;
    private Vector2 previewScrollPos;
    private Dictionary<string, List<ProtocolField>> protocolStructs = new Dictionary<string, List<ProtocolField>>();
    private bool isLoaded = false;
    
    // 输出格式选项
    private enum OutputFormat
    {
        Normal,         // 原始Markdown表格格式
        CompactFormat,  // 简洁缩进格式
        CollapsibleFormat // 可折叠格式
    }
    private OutputFormat selectedFormat = OutputFormat.Normal;
    
    // 格式对应的布尔值 - 改用布尔值记录选中状态
    private bool useNormalFormat = false;
    private bool useCompactFormat = false;
    private bool useCollapsibleFormat = true;
    
    // 保存路径相关
    private string saveDirectory = "";
    private const string SavePathKey = "ProtocolDocGenerator_SavePath";
    private const string OutputFormatKey = "ProtocolDocGenerator_OutputFormat";
    
    // 用于保存各格式选择状态的键
    private const string NormalFormatKey = "ProtocolDocGenerator_NormalFormat";
    private const string CompactFormatKey = "ProtocolDocGenerator_CompactFormat";
    private const string CollapsibleFormatKey = "ProtocolDocGenerator_CollapsibleFormat";
    
    // 是否包含关联结构体定义
    private bool includeReferencedStructs = true;
    
    // 是否显示详细日志
    private bool showDetailLog = false;

    // 保存协议文件列表相关
    private const string ProtocolFileListKey = "ProtocolDocGenerator_FileList";
    private const string ProtocolFileCountKey = "ProtocolDocGenerator_FileCount";
    
    // 保存选中的结构体名称
    private const string SelectedStructNameKey = "ProtocolDocGenerator_SelectedStructName";

    [MenuItem("Tools/ForAI/协议结构体文档生成器")]
    public static void ShowWindow()
    {
        GetWindow<ProtocolDocGenerator>("协议结构体文档生成器");
    }

    private void OnEnable()
    {
        // 加载上次保存的路径
        saveDirectory = EditorPrefs.GetString(SavePathKey, "");
        
        // 加载上次选择的输出格式
        if (EditorPrefs.HasKey(OutputFormatKey))
        {
            selectedFormat = (OutputFormat)EditorPrefs.GetInt(OutputFormatKey, 0);
        }
        
        // 加载格式选择状态
        useNormalFormat = EditorPrefs.GetBool(NormalFormatKey, false);
        useCompactFormat = EditorPrefs.GetBool(CompactFormatKey, false);
        useCollapsibleFormat = EditorPrefs.GetBool(CollapsibleFormatKey, true);
        
        // 确保至少有一种格式被选中
        if (!useNormalFormat && !useCompactFormat && !useCollapsibleFormat)
        {
            useNormalFormat = true;
        }
        
        // 加载保存的协议文件列表
        protocolFilePaths.Clear();
        int fileCount = EditorPrefs.GetInt(ProtocolFileCountKey, 0);
        for (int i = 0; i < fileCount; i++)
        {
            string filePath = EditorPrefs.GetString($"{ProtocolFileListKey}_{i}", "");
            if (!string.IsNullOrEmpty(filePath) && File.Exists(filePath))
            {
                protocolFilePaths.Add(filePath);
            }
        }
        
        // 如果没有保存的文件，使用默认文件路径
        if (protocolFilePaths.Count == 0 && !string.IsNullOrEmpty(currentProtocolPath) && File.Exists(currentProtocolPath))
        {
            protocolFilePaths.Add(currentProtocolPath);
        }
        
        // 根据加载的选择状态设置当前选中的格式
        UpdateSelectedFormat();
        
        // 加载选中的结构体名称
        inputStructName = EditorPrefs.GetString(SelectedStructNameKey, "");
    }
    
    private void OnDisable()
    {
        // 保存协议文件列表
        EditorPrefs.SetInt(ProtocolFileCountKey, protocolFilePaths.Count);
        for (int i = 0; i < protocolFilePaths.Count; i++)
        {
            EditorPrefs.SetString($"{ProtocolFileListKey}_{i}", protocolFilePaths[i]);
        }
        
        // 清除多余的文件路径
        int oldCount = EditorPrefs.GetInt(ProtocolFileCountKey, 0);
        for (int i = protocolFilePaths.Count; i < oldCount; i++)
        {
            EditorPrefs.DeleteKey($"{ProtocolFileListKey}_{i}");
        }
        
        // 保存选中的结构体名称
        EditorPrefs.SetString(SelectedStructNameKey, inputStructName);
    }

    private void OnGUI()
    {
        GUILayout.Label("协议结构体文档生成器", EditorStyles.boldLabel);

        // 文件路径输入
        EditorGUILayout.BeginHorizontal();
        currentProtocolPath = EditorGUILayout.TextField("协议文件路径:", currentProtocolPath);
        if (GUILayout.Button("浏览", GUILayout.Width(60)))
        {
            string path = EditorUtility.OpenFilePanel("选择协议文件", "Assets", "txt,lua");
            if (!string.IsNullOrEmpty(path))
            {
                string processedPath = path;
                
                // 如果选择的是项目内的文件，转换为Assets相对路径
                if (path.Contains(Application.dataPath))
                {
                    processedPath = "Assets" + path.Substring(Application.dataPath.Length);
                }
                
                currentProtocolPath = processedPath;
                
                // 如果文件不在列表中，则验证格式后添加
                if (!protocolFilePaths.Contains(processedPath))
                {
                    // 验证文件格式
                    bool isValidFormat = IsValidProtocolFormat(processedPath);
                    if (isValidFormat)
                    {
                        protocolFilePaths.Add(processedPath);
                        LoadSingleProtocolFile(processedPath);
                        
                        // 只有在之前没有加载状态时，才设置加载状态
                        if (!isLoaded)
                        {
                            isLoaded = protocolStructs.Count > 0;
                        }
                    }
                    else
                    {
                        EditorUtility.DisplayDialog("格式错误", $"文件格式错误: {Path.GetFileName(processedPath)}\n\n无法找到有效的协议数据，该文件将被忽略。", "确定");
                    }
                }
            }
        }
        EditorGUILayout.EndHorizontal();

        // 添加协议文件按钮
        EditorGUILayout.BeginHorizontal();
        if (GUILayout.Button("添加协议文件", GUILayout.Width(100)))
        {
            if (!string.IsNullOrEmpty(currentProtocolPath) && !protocolFilePaths.Contains(currentProtocolPath))
            {
                // 确保文件存在
                bool fileExists = File.Exists(currentProtocolPath);
                
                // 如果是Assets相对路径，可能需要转换为完整路径进行检查
                if (!fileExists && currentProtocolPath.StartsWith("Assets/"))
                {
                    string fullPath = Path.Combine(Application.dataPath, currentProtocolPath.Substring(7));
                    fileExists = File.Exists(fullPath);
                }
                
                if (fileExists)
                {
                    // 验证文件格式
                    bool isValidFormat = IsValidProtocolFormat(currentProtocolPath);
                    if (isValidFormat)
                    {
                        protocolFilePaths.Add(currentProtocolPath);
                        // 自动加载新添加的文件
                        LoadSingleProtocolFile(currentProtocolPath);
                    }
                    else
                    {
                        EditorUtility.DisplayDialog("格式错误", $"文件格式错误: {Path.GetFileName(currentProtocolPath)}\n\n无法找到有效的协议数据，该文件将被忽略。", "确定");
                    }
                }
                else
                {
                    Debug.LogWarning($"文件不存在: {currentProtocolPath}");
                    EditorUtility.DisplayDialog("警告", $"文件不存在: {currentProtocolPath}", "确定");
                }
            }
        }
        if (GUILayout.Button("清空列表", GUILayout.Width(100)))
        {
            if (protocolFilePaths.Count > 0)
            {
                protocolFilePaths.Clear();
                // 清空后重置结构体列表
                protocolStructs.Clear();
                isLoaded = false;
                outputDoc = "";
            }
        }
        EditorGUILayout.EndHorizontal();

        // 显示已添加的协议文件列表
        if (protocolFilePaths.Count > 0)
        {
            EditorGUILayout.LabelField("已添加的协议文件:");
            protocolListScrollPos = EditorGUILayout.BeginScrollView(protocolListScrollPos, GUILayout.Height(100));
            
            List<int> indicesToRemove = new List<int>();
            for (int i = 0; i < protocolFilePaths.Count; i++)
            {
                EditorGUILayout.BeginHorizontal();
                
                string filePath = protocolFilePaths[i];
                string displayPath = $"{i+1}. {filePath}";
                
                // 检查文件是否是Unity资源（以Assets开头的路径）
                bool isUnityAsset = filePath.StartsWith("Assets/") || filePath.Contains("/Assets/");
                
                // 如果是Unity资源，就创建一个可点击的链接
                if (isUnityAsset)
                {
                    // 从全路径提取相对于Assets的路径
                    string assetPath = filePath;
                    if (!filePath.StartsWith("Assets/") && filePath.Contains("/Assets/"))
                    {
                        int index = filePath.IndexOf("/Assets/");
                        assetPath = "Assets" + filePath.Substring(index + 7);
                    }
                    
                    // 获取文件对象
                    UnityEngine.Object fileObject = AssetDatabase.LoadAssetAtPath<UnityEngine.Object>(assetPath);
                    
                    if (fileObject != null)
                    {
                        // 创建可点击的对象引用字段
                        EditorGUILayout.ObjectField(new GUIContent($"{i+1}."), fileObject, typeof(UnityEngine.Object), false);
                    }
                    else
                    {
                        // 如果文件不存在或无法加载，显示普通文本
                        EditorGUILayout.LabelField(displayPath, EditorStyles.wordWrappedLabel);
                    }
                }
                else
                {
                    // 非Unity资源显示普通文本
                    EditorGUILayout.LabelField(displayPath, EditorStyles.wordWrappedLabel);
                }
                
                if (GUILayout.Button("X", GUILayout.Width(20)))
                {
                    indicesToRemove.Add(i);
                }
                EditorGUILayout.EndHorizontal();
            }
            
            // 删除标记的文件
            if (indicesToRemove.Count > 0)
            {
                // 保存要删除的文件路径
                List<string> filesToRemove = new List<string>();
                for (int i = 0; i < indicesToRemove.Count; i++)
                {
                    filesToRemove.Add(protocolFilePaths[indicesToRemove[i]]);
                }
                
                // 从列表中删除文件
                for (int i = indicesToRemove.Count - 1; i >= 0; i--)
                {
                    protocolFilePaths.RemoveAt(indicesToRemove[i]);
                }
                
                // 删除文件后重新加载所有结构体
                ReloadAllProtocolFiles();
            }
            
            EditorGUILayout.EndScrollView();
        }

        // 添加拖拽区域
        Rect dropArea = GUILayoutUtility.GetRect(0.0f, 50.0f, GUILayout.ExpandWidth(true));

        // 创建自定义样式
        GUIStyle dropBoxStyle = new GUIStyle(EditorStyles.helpBox);
        dropBoxStyle.alignment = TextAnchor.MiddleCenter;
        dropBoxStyle.fontStyle = FontStyle.Bold;

        // 绘制拖拽区域
        Color originalColor = GUI.color;
        GUI.color = new Color(0.8f, 0.8f, 1.0f, 0.8f);
        GUI.Box(dropArea, "拖拽协议文件到这里", dropBoxStyle);

        // 处理拖拽事件
        Event evt = Event.current;
        switch (evt.type)
        {
            case EventType.DragUpdated:
            case EventType.DragPerform:
                if (!dropArea.Contains(evt.mousePosition))
                    break;
                    
                // 改变鼠标指针为可接受状态
                DragAndDrop.visualMode = DragAndDropVisualMode.Copy;
                
                // 高亮拖拽区域
                if (evt.type == EventType.DragUpdated)
                {
                    GUI.color = new Color(0.7f, 0.9f, 1.0f, 0.9f);
                    GUI.Box(dropArea, "释放鼠标添加文件", dropBoxStyle);
                    Repaint();
                }
                
                if (evt.type == EventType.DragPerform)
                {
                    DragAndDrop.AcceptDrag();
                    
                    bool needReload = false;
                    List<string> validFiles = new List<string>();
                    
                    // 先检查所有文件的格式，只添加有效的文件
                    foreach (string path in DragAndDrop.paths)
                    {
                        if (File.Exists(path) && (path.EndsWith(".txt") || path.EndsWith(".lua")))
                        {
                            string processedPath = path;
                            
                            // 处理Unity项目内的资源路径，确保使用Assets相对路径
                            if (path.Contains("/Assets/") && !path.StartsWith("Assets/"))
                            {
                                int index = path.IndexOf("/Assets/");
                                processedPath = "Assets" + path.Substring(index + 7);
                                
                                // 验证处理后的路径是否有效
                                if (!File.Exists(processedPath) && !string.IsNullOrEmpty(Application.dataPath))
                                {
                                    // 尝试构建完整路径
                                    string fullPath = Path.Combine(Application.dataPath, processedPath.Substring(7));
                                    if (File.Exists(fullPath))
                                    {
                                        processedPath = path; // 使用原始路径
                                    }
                                }
                            }
                            
                            // 如果文件已经在列表中，跳过
                            if (protocolFilePaths.Contains(processedPath))
                            {
                                continue;
                            }
                            
                            // 验证文件格式
                            bool isValidFormat = IsValidProtocolFormat(processedPath);
                            if (isValidFormat)
                            {
                                validFiles.Add(processedPath);
                            }
                            else
                            {
                                // 对于格式错误的文件显示警告
                                Debug.LogWarning($"文件格式错误: {processedPath}");
                                EditorUtility.DisplayDialog("格式错误", $"文件格式错误: {Path.GetFileName(processedPath)}\n\n无法找到协议数据 [[...]]，该文件将被忽略。", "确定");
                            }
                        }
                    }
                    
                    // 添加所有有效的文件
                    foreach (string validPath in validFiles)
                    {
                        protocolFilePaths.Add(validPath);
                        // 单独加载新添加的文件
                        LoadSingleProtocolFile(validPath);
                        needReload = true;
                    }
                    
                    // 如果有添加新文件，则更新状态
                    if (needReload)
                    {
                        // 只有在之前没有加载状态时，才设置加载状态
                        if (!isLoaded)
                        {
                            isLoaded = protocolStructs.Count > 0;
                        }
                    }
                }
                
                evt.Use();
                break;
        }

        // 恢复原始颜色
        GUI.color = originalColor;

        // 加载协议文件按钮
        if (GUILayout.Button("加载协议文件"))
        {
            // 重新加载所有文件
            ReloadAllProtocolFiles();
        }

        if (isLoaded)
        {
            EditorGUILayout.Space();
            EditorGUILayout.LabelField($"已加载 {protocolStructs.Count} 个结构体");

            // 文档保存路径
            EditorGUILayout.BeginHorizontal();
            saveDirectory = EditorGUILayout.TextField("保存目录:", saveDirectory);
            if (GUILayout.Button("浏览", GUILayout.Width(60)))
            {
                string path = EditorUtility.SaveFolderPanel("选择保存目录", saveDirectory, "");
                if (!string.IsNullOrEmpty(path))
                {
                    saveDirectory = path;
                    // 保存路径
                    EditorPrefs.SetString(SavePathKey, saveDirectory);
                    // 强制刷新UI
                    Repaint();
                }
            }
            EditorGUILayout.EndHorizontal();
            
            // 选项：输出格式
            EditorGUILayout.LabelField("输出格式:", EditorStyles.boldLabel);
            
            EditorGUILayout.BeginVertical(EditorStyles.helpBox);
            
            // 可折叠格式选项
            bool prevCollapsibleFormat = useCollapsibleFormat;
            useCollapsibleFormat = EditorGUILayout.ToggleLeft("可折叠格式 (Collapsible Format) - MD格式", useCollapsibleFormat);
            
            // 简洁缩进格式选项
            bool prevCompactFormat = useCompactFormat;
            useCompactFormat = EditorGUILayout.ToggleLeft("简洁缩进格式 (Compact Format)", useCompactFormat);
            
            // 原始格式选项
            bool prevNormalFormat = useNormalFormat;
            useNormalFormat = EditorGUILayout.ToggleLeft("Markdown表格格式 (Normal)", useNormalFormat);
            
            EditorGUILayout.EndVertical();
            
            // 如果有变化，更新选中的格式并重新生成文档
            if (prevNormalFormat != useNormalFormat || 
                prevCompactFormat != useCompactFormat || 
                prevCollapsibleFormat != useCollapsibleFormat)
            {
                // 确保至少有一种格式被选中
                if (!useNormalFormat && !useCompactFormat && !useCollapsibleFormat)
                {
                    // 如果尝试取消所有选项，恢复之前的选择
                    useNormalFormat = prevNormalFormat;
                    useCompactFormat = prevCompactFormat;
                    useCollapsibleFormat = prevCollapsibleFormat;
                    
                    // 如果仍然没有选中项（不应该发生），强制选中第一项
                    if (!useNormalFormat && !useCompactFormat && !useCollapsibleFormat)
                    {
                        useNormalFormat = true;
                    }
                }
                
                // 更新选中的格式并保存
                UpdateSelectedFormat();
                
                // 重新生成文档
                if (!string.IsNullOrEmpty(inputStructName) && protocolStructs.ContainsKey(inputStructName))
                {
                    GenerateDoc();
                    // 强制刷新UI
                    Repaint();
                }
            }
            
            // 选项：是否包含关联结构体
            includeReferencedStructs = EditorGUILayout.Toggle("包含关联结构体定义", includeReferencedStructs);
            
            // 选项：是否显示详细日志
            showDetailLog = EditorGUILayout.Toggle("显示详细日志", showDetailLog);
            
            // 生成文档按钮
            if (GUILayout.Button("生成文档到文件", GUILayout.Height(30)))
            {
                GenerateAndSaveDoc();
            }
            
            // 测试递归引用按钮 - 调试用
            if (GUILayout.Button("测试递归引用", GUILayout.Height(30)))
            {
                if (string.IsNullOrEmpty(inputStructName))
                {
                    EditorUtility.DisplayDialog("提示", "请输入结构体名称", "确定");
                    return;
                }
                TestRecursiveReferences(inputStructName);
            }
            
            // 输入结构体名称 - 放在按钮下面，列表上面
            EditorGUILayout.Space(10);
            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.LabelField("输入结构体名称:", GUILayout.Width(100));
            
            // 使用EditorGUILayout.TextField直接实现，更简洁且可靠
            GUI.SetNextControlName("StructNameInput");
            string newInputStructName = EditorGUILayout.TextField(inputStructName, GUILayout.ExpandWidth(true));
            
            // 如果输入字段的内容发生变化，则重新生成文档
            if (newInputStructName != inputStructName)
            {
                inputStructName = newInputStructName;
                
                // 保存选中的结构体名称
                EditorPrefs.SetString(SelectedStructNameKey, inputStructName);
                
                if (!string.IsNullOrEmpty(inputStructName) && protocolStructs.ContainsKey(inputStructName))
                {
                    GenerateDoc();
                    // 强制刷新UI
                    Repaint();
                }
            }
            
            EditorGUILayout.EndHorizontal();

            // 显示所有结构体名称
            EditorGUILayout.LabelField("可用结构体列表:");
            EditorGUILayout.BeginVertical(EditorStyles.helpBox);
            scrollPos = EditorGUILayout.BeginScrollView(scrollPos, GUILayout.Height(200));

            // 为拖拽准备数据
            Vector2 mousePos = Vector2.zero;
            if (Event.current.type == EventType.MouseDown)
            {
                mousePos = Event.current.mousePosition;
            }

            foreach (var structName in protocolStructs.Keys.OrderBy(k => k))
            {
                EditorGUILayout.BeginHorizontal();
                
                // 检查鼠标位置是否在当前行上
                Rect buttonRect = GUILayoutUtility.GetRect(new GUIContent(structName), EditorStyles.label);
                
                // 处理点击选择
                if (GUI.Button(buttonRect, structName, EditorStyles.label))
                {
                    // 设置输入框内容为选中的结构体名称
                    inputStructName = structName;
                    
                    // 保存选中的结构体名称
                    EditorPrefs.SetString(SelectedStructNameKey, inputStructName);
                    
                    // 确保焦点从输入框移开，以便下次绘制时显示新值
                    GUI.FocusControl(null);
                    
                    // 预览
                    GenerateDoc();
                    
                    // 强制刷新UI
                    Repaint();
                }
                
                // 处理拖拽开始
                if (Event.current.type == EventType.MouseDrag && buttonRect.Contains(mousePos) && !string.IsNullOrEmpty(structName))
                {
                    // 设置拖拽数据
                    DragAndDrop.PrepareStartDrag();
                    DragAndDrop.SetGenericData("StructName", structName);
                    DragAndDrop.StartDrag("结构体名称");
                    
                    // 使用事件
                    Event.current.Use();
                }
                
                EditorGUILayout.EndHorizontal();
            }
            EditorGUILayout.EndScrollView();
            EditorGUILayout.EndVertical();

            // 预览区域
            if (!string.IsNullOrEmpty(outputDoc))
            {
                EditorGUILayout.Space();
                
                // 计算选中的格式数量
                int selectedCount = 0;
                if (useNormalFormat) selectedCount++;
                if (useCompactFormat) selectedCount++;
                if (useCollapsibleFormat) selectedCount++;
                
                // 根据当前选中的格式显示预览标题
                string formatName = "未知格式";
                if (selectedFormat == OutputFormat.Normal)
                    formatName = "Markdown表格格式";
                else if (selectedFormat == OutputFormat.CompactFormat)
                    formatName = "简洁缩进格式";
                else if (selectedFormat == OutputFormat.CollapsibleFormat)
                    formatName = "可折叠格式";
                
                EditorGUILayout.LabelField($"文档预览 ({formatName}) - 已选择{selectedCount}种格式");
                
                EditorGUILayout.BeginVertical(EditorStyles.textArea);
                
                // 修复滚动问题：使用类变量存储滚动位置，而非临时变量
                previewScrollPos = EditorGUILayout.BeginScrollView(previewScrollPos, GUILayout.Height(200));
                GUIStyle textAreaStyle = new GUIStyle(EditorStyles.textArea);
                textAreaStyle.wordWrap = true;
                EditorGUILayout.TextArea(outputDoc, textAreaStyle, GUILayout.ExpandHeight(true));
                EditorGUILayout.EndScrollView();
                
                EditorGUILayout.EndVertical();
                
                // 复制到剪贴板按钮
                if (GUILayout.Button("复制到剪贴板"))
                {
                    EditorGUIUtility.systemCopyBuffer = outputDoc;
                    Debug.Log("文档已复制到剪贴板!");
                }
            }
        }
    }
    
    // 测试递归引用函数 - 调试用
    private void TestRecursiveReferences(string structName)
    {
        if (!protocolStructs.ContainsKey(structName))
        {
            Debug.LogError($"结构体 {structName} 不存在");
            return;
        }
        
        HashSet<string> allReferencedTypes = new HashSet<string>();
        Dictionary<string, HashSet<string>> referenceMap = new Dictionary<string, HashSet<string>>();
        
        // 使用BFS算法查找所有引用的结构体
        Queue<string> queue = new Queue<string>();
        queue.Enqueue(structName);
        HashSet<string> visited = new HashSet<string> { structName };
        
        while (queue.Count > 0)
        {
            string currentStruct = queue.Dequeue();
            
            if (!protocolStructs.ContainsKey(currentStruct))
            {
                continue;
            }
            
            if (!referenceMap.ContainsKey(currentStruct))
            {
                referenceMap[currentStruct] = new HashSet<string>();
            }
            
            foreach (var field in protocolStructs[currentStruct])
            {
                string baseType = GetBaseType(field.Type);
                
                if (protocolStructs.ContainsKey(baseType) && baseType != currentStruct)
                {
                    Debug.Log($"Found reference: {currentStruct} -> {baseType} (via field {field.Name})");
                    
                    if (baseType != structName) // 避免添加起始结构体
                    {
                        allReferencedTypes.Add(baseType);
                    }
                    
                    referenceMap[currentStruct].Add(baseType);
                    
                    if (!visited.Contains(baseType))
                    {
                        visited.Add(baseType);
                        queue.Enqueue(baseType);
                    }
                }
            }
        }
        
        Debug.Log($"All references for {structName}: {string.Join(", ", allReferencedTypes)}");
        
        foreach (var kvp in referenceMap)
        {
            if (kvp.Value.Count > 0)
            {
                Debug.Log($"{kvp.Key} 引用: {string.Join(", ", kvp.Value)}");
            }
        }
    }

    private void LoadProtocolFiles()
    {
        try
        {
            // 检查是否有文件要加载
            if (protocolFilePaths.Count == 0)
            {
                // 如果没有添加任何文件，但当前路径有效，则添加当前路径
                if (!string.IsNullOrEmpty(currentProtocolPath) && File.Exists(currentProtocolPath))
                {
                    protocolFilePaths.Add(currentProtocolPath);
                }
                else
                {
                    EditorUtility.DisplayDialog("提示", "请先添加协议文件", "确定");
                    return;
                }
            }
            
            // 清空现有结构体
            protocolStructs.Clear();
            int successCount = 0;
            int totalCount = protocolFilePaths.Count;
            List<string> errorFiles = new List<string>();
            
            EditorUtility.DisplayProgressBar("加载协议文件", "正在准备...", 0);
            
            for (int i = 0; i < protocolFilePaths.Count; i++)
            {
                var filePath = protocolFilePaths[i];
                
                try
                {
                    if (!File.Exists(filePath))
                    {
                        Debug.LogError($"文件不存在: {filePath}");
                        errorFiles.Add($"{Path.GetFileName(filePath)} (文件不存在)");
                        continue;
                    }
                    
                    EditorUtility.DisplayProgressBar("加载协议文件", 
                        $"正在加载 {Path.GetFileName(filePath)}...", 
                        (float)i / totalCount);
                    
                    string content = File.ReadAllText(filePath);
                    
                    // 提取Lua字符串中的JSON数据
                    int startIndex = content.IndexOf("[[");
                    int endIndex = content.LastIndexOf("]]");
                    
                    if (startIndex != -1 && endIndex != -1)
                    {
                        string jsonText = content.Substring(startIndex + 2, endIndex - startIndex - 2).Trim();
                        
                        // 解析JSON数据以提取结构体定义
                        int beforeCount = protocolStructs.Count;
                        ParseProtocolStructs(jsonText);
                        int afterCount = protocolStructs.Count;
                        
                        int newStructsCount = afterCount - beforeCount;
                        Debug.Log($"从文件 {Path.GetFileName(filePath)} 中加载了 {newStructsCount} 个结构体");
                        successCount++;
                    }
                    else
                    {
                        Debug.LogError($"文件格式错误 (无法找到 [[...]]): {filePath}");
                        errorFiles.Add($"{Path.GetFileName(filePath)} (格式错误)");
                    }
                }
                catch (Exception ex)
                {
                    Debug.LogError($"处理文件 {filePath} 时出错: {ex.Message}");
                    errorFiles.Add($"{Path.GetFileName(filePath)} ({ex.Message})");
                }
            }
            
            EditorUtility.ClearProgressBar();
            
            if (protocolStructs.Count > 0)
            {
                isLoaded = true;
                
                string resultMessage = $"成功加载 {successCount}/{totalCount} 个协议文件\n";
                resultMessage += $"共解析出 {protocolStructs.Count} 个结构体";
                
                if (errorFiles.Count > 0)
                {
                    resultMessage += "\n\n加载失败的文件:";
                    foreach (var file in errorFiles)
                    {
                        resultMessage += $"\n- {file}";
                    }
                }
                
                EditorUtility.DisplayDialog("加载完成", resultMessage, "确定");
                
                if (showDetailLog)
                {
                    // 输出所有加载的结构体名称
                    StringBuilder sb = new StringBuilder();
                    sb.AppendLine("已加载的结构体:");
                    foreach (var structName in protocolStructs.Keys.OrderBy(k => k))
                    {
                        sb.AppendLine($"- {structName}");
                    }
                    Debug.Log(sb.ToString());
                }
            }
            else
            {
                isLoaded = false;
                EditorUtility.DisplayDialog("错误", "未能从任何文件中加载协议结构体", "确定");
            }
        }
        catch (Exception e)
        {
            EditorUtility.ClearProgressBar();
            Debug.LogError($"加载协议文件失败: {e.Message}");
            EditorUtility.DisplayDialog("错误", $"加载协议文件失败: {e.Message}", "确定");
            isLoaded = false;
        }
    }
    
    private void ParseProtocolStructs(string jsonText)
    {
        // 去掉首尾空白
        jsonText = jsonText.Trim();
        
        // 确保是一个JSON对象
        if (!jsonText.StartsWith("{") || !jsonText.EndsWith("}"))
        {
            Debug.LogError("JSON格式不正确，应该是一个对象 {");
            return;
        }
        
        try
        {
            // 移除最外层的大括号，得到内部内容
            string innerContent = jsonText.Substring(1, jsonText.Length - 2).Trim();
            
            // 在顶层分割各个结构体定义
            int startPos = 0;
            int depth = 0;
            bool inQuotes = false;
            bool escaped = false;
            
            StringBuilder currentKey = new StringBuilder();
            bool collectingKey = false;
            string currentStructName = null;
            int structValueStartPos = -1;
            
            for (int i = 0; i < innerContent.Length; i++)
            {
                char c = innerContent[i];
                
                // 处理转义字符
                if (c == '\\' && !escaped)
                {
                    escaped = true;
                    continue;
                }
                
                // 处理引号
                if (c == '"' && !escaped)
                {
                    inQuotes = !inQuotes;
                    
                    // 开始或结束收集键名
                    if (depth == 0)
                    {
                        if (inQuotes)
                        {
                            // 开始收集键名
                            collectingKey = true;
                            currentKey.Clear();
                        }
                        else if (collectingKey)
                        {
                            // 结束收集键名
                            collectingKey = false;
                            currentStructName = currentKey.ToString();
                        }
                    }
                }
                else if (collectingKey && inQuotes)
                {
                    // 收集键名
                    currentKey.Append(c);
                }
                
                // 检测结构体值的开始
                if (c == '[' && !inQuotes)
                {
                    depth++;
                    if (depth == 1 && currentStructName != null)
                    {
                        // 找到结构体值的开始位置
                        structValueStartPos = i;
                    }
                }
                // 检测结构体值的结束
                else if (c == ']' && !inQuotes)
                {
                    depth--;
                    if (depth == 0 && currentStructName != null && structValueStartPos != -1)
                    {
                        // 提取字段列表文本
                        string fieldsText = innerContent.Substring(structValueStartPos + 1, i - structValueStartPos - 1).Trim();
                        
                        // 解析字段
                        List<ProtocolField> fields = ParseFields(fieldsText);
                        
                        // 添加到结构体字典 - 修改为始终添加，即使字段为空
                        protocolStructs[currentStructName] = fields;
                        if (showDetailLog)
                        {
                            Debug.Log($"解析结构体: {currentStructName}, 包含 {fields.Count} 个字段");
                        }
                        
                        // 重置状态
                        currentStructName = null;
                        structValueStartPos = -1;
                    }
                }
                
                // 重置转义状态
                escaped = false;
            }
            
            if (showDetailLog)
            {
                Debug.Log($"解析完成，共找到 {protocolStructs.Count} 个结构体");
            }
        }
        catch (Exception ex)
        {
            Debug.LogError($"解析协议结构体时出错: {ex.Message}\n{ex.StackTrace}");
        }
    }
    
    private int FindMatchingBracket(string text, int openBracketIndex)
    {
        int depth = 1;
        for (int i = openBracketIndex + 1; i < text.Length; i++)
        {
            if (text[i] == '[')
            {
                depth++;
            }
            else if (text[i] == ']')
            {
                depth--;
                if (depth == 0)
                {
                    return i;
                }
            }
        }
        return -1; // 没有找到匹配的括号
    }
    
    private List<ProtocolField> ParseFields(string fieldsText)
    {
        List<ProtocolField> fields = new List<ProtocolField>();
        int position = 0;
        
        while (position < fieldsText.Length)
        {
            // 查找下一个字段定义的开始
            int fieldStart = fieldsText.IndexOf("{", position);
            if (fieldStart == -1) break;
            
            // 查找字段定义的结束
            int fieldEnd = FindMatchingBrace(fieldsText, fieldStart);
            if (fieldEnd == -1) break;
            
            // 提取字段定义文本
            string fieldText = fieldsText.Substring(fieldStart, fieldEnd - fieldStart + 1).Trim();
            
            // 解析字段信息
            ProtocolField field = ParseFieldInfo(fieldText);
            if (field != null)
            {
                fields.Add(field);
            }
            
            // 移动到下一个字段
            position = fieldEnd + 1;
        }
        
        return fields;
    }
    
    private int FindMatchingBrace(string text, int openBraceIndex)
    {
        int depth = 1;
        for (int i = openBraceIndex + 1; i < text.Length; i++)
        {
            if (text[i] == '{')
            {
                depth++;
            }
            else if (text[i] == '}')
            {
                depth--;
                if (depth == 0)
                {
                    return i;
                }
            }
        }
        return -1; // 没有找到匹配的大括号
    }
    
    private ProtocolField ParseFieldInfo(string fieldText)
    {
        try
        {
            // 创建一个新字段对象
            ProtocolField field = new ProtocolField();
            
            // 提取字段名
            string fieldNamePattern = "\"field\":\"([^\"]+)\"";
            Match fieldMatch = Regex.Match(fieldText, fieldNamePattern);
            if (fieldMatch.Success)
            {
                field.Name = fieldMatch.Groups[1].Value;
            }
            else
            {
                return null; // 没有找到字段名
            }
            
            // 提取类型
            string typePattern = "\"type\":\"([^\"]+)\"";
            Match typeMatch = Regex.Match(fieldText, typePattern);
            if (typeMatch.Success)
            {
                field.Type = typeMatch.Groups[1].Value;
            }
            else
            {
                return null; // 没有找到类型
            }
            
            // 提取说明
            string explainPattern = "\"explain\":\"([^\"]+)\"";
            Match explainMatch = Regex.Match(fieldText, explainPattern);
            if (explainMatch.Success)
            {
                field.Description = explainMatch.Groups[1].Value;
            }
            else
            {
                field.Description = ""; // 没有找到说明，使用空字符串
            }
            
            return field;
        }
        catch (Exception ex)
        {
            Debug.LogError($"解析字段信息时出错: {ex.Message}, 字段文本: {fieldText}");
            return null;
        }
    }

    private void GenerateAndSaveDoc()
    {
        if (string.IsNullOrEmpty(inputStructName))
        {
            EditorUtility.DisplayDialog("提示", "请输入结构体名称", "确定");
            return;
        }

        if (!protocolStructs.ContainsKey(inputStructName))
        {
            EditorUtility.DisplayDialog("提示", $"未找到名为 '{inputStructName}' 的结构体", "确定");
            return;
        }

        if (string.IsNullOrEmpty(saveDirectory))
        {
            string path = EditorUtility.SaveFolderPanel("选择保存目录", "", "");
            if (string.IsNullOrEmpty(path))
            {
                return; // 用户取消了选择
            }
            saveDirectory = path;
            // 保存路径
            EditorPrefs.SetString(SavePathKey, saveDirectory);
            // 强制刷新UI
            Repaint();
        }
        else 
        {
            // 验证目录是否存在
            if (!Directory.Exists(saveDirectory))
            {
                if (EditorUtility.DisplayDialog("目录不存在", $"保存目录不存在: {saveDirectory}\n\n是否重新选择?", "选择目录", "取消"))
                {
                    string path = EditorUtility.SaveFolderPanel("选择保存目录", "", "");
                    if (string.IsNullOrEmpty(path))
                    {
                        return; // 用户取消了选择
                    }
                    saveDirectory = path;
                    // 保存路径
                    EditorPrefs.SetString(SavePathKey, saveDirectory);
                    // 强制刷新UI
                    Repaint();
                }
                else
                {
                    return; // 用户取消
                }
            }
        }

        // 检查是否至少选择了一种格式
        if (!useNormalFormat && !useCompactFormat && !useCollapsibleFormat)
        {
            EditorUtility.DisplayDialog("提示", "请至少选择一种输出格式", "确定");
            return;
        }

        try
        {
            int successCount = 0;
            List<string> exportedFiles = new List<string>();
            
            // 导出所有选中的格式
            if (useNormalFormat)
            {
                string filePath = ExportSpecificFormat(OutputFormat.Normal, "_normal");
                if (!string.IsNullOrEmpty(filePath))
                {
                    successCount++;
                    exportedFiles.Add(filePath);
                }
            }
            
            if (useCompactFormat)
            {
                string filePath = ExportSpecificFormat(OutputFormat.CompactFormat, "_compact");
                if (!string.IsNullOrEmpty(filePath))
                {
                    successCount++;
                    exportedFiles.Add(filePath);
                }
            }
            
            if (useCollapsibleFormat)
            {
                string filePath = ExportSpecificFormat(OutputFormat.CollapsibleFormat, "_collapsible");
                if (!string.IsNullOrEmpty(filePath))
                {
                    successCount++;
                    exportedFiles.Add(filePath);
                }
            }
            
            // 显示导出结果
            if (successCount > 0)
            {
                StringBuilder resultMessage = new StringBuilder();
                resultMessage.AppendLine($"成功导出 {successCount} 种格式的文档:");
                
                foreach (var file in exportedFiles)
                {
                    resultMessage.AppendLine(file);
                }
                
                EditorUtility.DisplayDialog("成功", resultMessage.ToString(), "确定");
            }
            else
            {
                EditorUtility.DisplayDialog("错误", "导出文档过程中出现错误，请查看控制台日志", "确定");
            }
        }
        catch (Exception ex)
        {
            Debug.LogError($"保存文档时出错: {ex.Message}");
            EditorUtility.DisplayDialog("错误", $"保存文档时出错: {ex.Message}", "确定");
        }
    }
    
    // 导出特定格式的文档
    private string ExportSpecificFormat(OutputFormat format, string suffix)
    {
        try
        {
            // 临时保存原来的选中格式
            OutputFormat originalFormat = selectedFormat;
            selectedFormat = format;
            
            // 生成文档内容
            GenerateDoc();
            
            // 保存到文件
            string finalSuffix = suffix;
            if (format == OutputFormat.CollapsibleFormat)
            {
                // 对于MD格式（可折叠格式），不加后缀
                finalSuffix = "";
            }
            
            string filePath = Path.Combine(saveDirectory, $"{inputStructName}{finalSuffix}.md");
            File.WriteAllText(filePath, outputDoc, Encoding.UTF8);
            Debug.Log($"文档已保存到: {filePath}");
            
            // 恢复原来的选中格式
            selectedFormat = originalFormat;
            
            return filePath;
        }
        catch (Exception ex)
        {
            Debug.LogError($"导出 {format} 格式文档时出错: {ex.Message}");
            return null;
        }
    }

    private void GenerateDoc()
    {
        if (string.IsNullOrEmpty(inputStructName) || !protocolStructs.ContainsKey(inputStructName))
        {
            outputDoc = "";
            return;
        }

        StringBuilder sb = new StringBuilder();
        
        // 收集所有引用的结构体，包括多级引用 - 使用BFS算法替代递归
        HashSet<string> allReferencedTypes = new HashSet<string>();
        Dictionary<string, HashSet<string>> structReferences = new Dictionary<string, HashSet<string>>();
        
        // 使用BFS算法查找所有引用
        CollectReferencesUsingBFS(inputStructName, allReferencedTypes, structReferences);
        
        if (selectedFormat == OutputFormat.Normal)
        {
            // 生成主结构体文档 - 原始Markdown表格格式
            GenerateMainStructDoc(inputStructName, sb, structReferences);
            
            // 如果启用了包含关联结构体，生成所有引用的结构体定义
            if (includeReferencedStructs && allReferencedTypes.Count > 0)
            {
                sb.AppendLine();
                sb.AppendLine("---");
                sb.AppendLine();
                sb.AppendLine("# 引用的结构体定义");
                sb.AppendLine();
                
                foreach (var type in allReferencedTypes.OrderBy(t => t))
                {
                    GenerateReferencedStructDoc(type, sb, structReferences);
                }
            }
        }
        else if (selectedFormat == OutputFormat.CompactFormat)
        {
            // 简洁缩进格式
            GenerateCompactFormatDoc(inputStructName, sb, allReferencedTypes, structReferences);
        }
        else if (selectedFormat == OutputFormat.CollapsibleFormat)
        {
            // 可折叠格式
            GenerateCollapsibleFormatDoc(inputStructName, sb, allReferencedTypes, structReferences);
        }
        
        if (showDetailLog)
        {
            Debug.Log($"收集到的所有引用类型: {string.Join(", ", allReferencedTypes)}");
            foreach(var kvp in structReferences)
            {
                Debug.Log($"{kvp.Key} 引用: {string.Join(", ", kvp.Value)}");
            }
        }

        outputDoc = sb.ToString();
    }
    
    // 使用BFS算法收集所有引用关系
    private void CollectReferencesUsingBFS(string startStructName, HashSet<string> allReferencedTypes, Dictionary<string, HashSet<string>> structReferences)
    {
        Queue<string> queue = new Queue<string>();
        HashSet<string> visited = new HashSet<string> { startStructName };
        
        queue.Enqueue(startStructName);
        
        while (queue.Count > 0)
        {
            string structName = queue.Dequeue();
            
            if (!protocolStructs.ContainsKey(structName))
            {
                continue;
            }
            
            if (!structReferences.ContainsKey(structName))
            {
                structReferences[structName] = new HashSet<string>();
            }
            
            foreach (var field in protocolStructs[structName])
            {
                string baseType = GetBaseType(field.Type);
                
                if (protocolStructs.ContainsKey(baseType) && baseType != structName)
                {
                    if (showDetailLog)
                    {
                        Debug.Log($"引用关系: {structName} -> {baseType} (字段: {field.Name})");
                    }
                    
                    structReferences[structName].Add(baseType);
                    
                    if (baseType != startStructName) // 不将起始结构体添加到引用列表
                    {
                        allReferencedTypes.Add(baseType);
                    }
                    
                    if (!visited.Contains(baseType))
                    {
                        visited.Add(baseType);
                        queue.Enqueue(baseType);
                    }
                }
            }
        }
    }
    
    // 生成主结构体文档
    private void GenerateMainStructDoc(string structName, StringBuilder sb, Dictionary<string, HashSet<string>> structReferences)
    {
        if (!protocolStructs.ContainsKey(structName))
        {
            sb.AppendLine($"## {structName} (未定义)");
            sb.AppendLine("找不到此结构体的定义。");
            sb.AppendLine();
            return;
        }
        
        sb.AppendLine($"# {structName} 结构体文档");
        sb.AppendLine();
        
        var fields = protocolStructs[structName];
        
        // 检查是否为空协议
        if (fields.Count == 0)
        {
            sb.AppendLine("此协议不包含任何字段（空协议）。");
            sb.AppendLine();
            sb.AppendLine("通常空协议用于简单的请求，不需要传递任何参数。");
            sb.AppendLine();
            return;
        }
        
        sb.AppendLine("## 字段列表");
        sb.AppendLine();
        sb.AppendLine("| 字段名 | 类型 | 是否可选 | 说明 |");
        sb.AppendLine("|--------|------|----------|------|");

        foreach (var field in fields)
        {
            bool isOptional = field.Type.EndsWith("*");
            string type = isOptional ? field.Type.TrimEnd('*') : field.Type;
            sb.AppendLine($"| {field.Name} | {type} | {(isOptional ? "是" : "否")} | {field.Description} |");
        }

        sb.AppendLine();
        sb.AppendLine("## 类型说明");
        sb.AppendLine();
        
        // 添加引用的结构体说明
        if (structReferences.TryGetValue(structName, out HashSet<string> directRefs) && directRefs.Count > 0)
        {
            sb.AppendLine("此结构体引用了以下结构体类型：");
            sb.AppendLine();
            foreach (var type in directRefs.OrderBy(t => t))
            {
                // 修复锚点格式 - 使用小写并去除空格
                sb.AppendLine($"- [{type}](#-{type.ToLowerInvariant()})");
            }
        }
        else
        {
            sb.AppendLine("此结构体未引用其他结构体类型。");
        }
    }
    
    private void GenerateReferencedStructDoc(string structName, StringBuilder sb, Dictionary<string, HashSet<string>> structReferences)
    {
        sb.AppendLine("---");
        sb.AppendLine();
        sb.AppendLine($"## {structName}");
        sb.AppendLine();
        
        if (!protocolStructs.ContainsKey(structName))
        {
            sb.AppendLine("**结构体未定义**");
            sb.AppendLine();
            return;
        }
        
        var fields = protocolStructs[structName];
        
        // 检查是否为空协议
        if (fields.Count == 0)
        {
            sb.AppendLine("此协议不包含任何字段（空协议）。");
            sb.AppendLine();
            sb.AppendLine("通常空协议用于简单的请求，不需要传递任何参数。");
            sb.AppendLine();
            return;
        }
        
        sb.AppendLine("| 字段名 | 类型 | 是否可选 | 说明 |");
        sb.AppendLine("|--------|------|----------|------|");
        
        foreach (var field in fields)
        {
            bool isOptional = field.Type.EndsWith("*");
            string fieldType = isOptional ? field.Type.TrimEnd('*') : field.Type;
            sb.AppendLine($"| {field.Name} | {fieldType} | {(isOptional ? "是" : "否")} | {field.Description} |");
        }
        
        // 显示此结构体引用的其他结构体
        if (structReferences.TryGetValue(structName, out HashSet<string> references) && references.Count > 0)
        {
            sb.AppendLine();
            sb.AppendLine("此结构体引用了以下结构体类型：");
            sb.AppendLine();
            foreach (var refType in references.OrderBy(t => t))
            {
                // 修复锚点格式
                sb.AppendLine($"- [{refType}](#-{refType.ToLowerInvariant()})");
            }
        }
        
        sb.AppendLine();
    }
    
    // 生成简洁缩进格式文档
    private void GenerateCompactFormatDoc(string structName, StringBuilder sb, HashSet<string> allReferencedTypes, Dictionary<string, HashSet<string>> structReferences)
    {
        sb.AppendLine($"# {structName} 结构体文档");
        sb.AppendLine();
        sb.AppendLine("```");
        sb.AppendLine(structName);
        
        if (!protocolStructs.ContainsKey(structName))
        {
            sb.AppendLine("    // 结构体未定义");
            sb.AppendLine("```");
            return;
        }
        
        var fields = protocolStructs[structName];
        
        // 检查是否为空协议
        if (fields.Count == 0)
        {
            sb.AppendLine("    // 空协议，不包含任何字段");
            sb.AppendLine("```");
            return;
        }
        
        // 创建一个已处理结构体的集合，避免重复处理
        HashSet<string> processedStructs = new HashSet<string>();
        
        // 添加主结构体及其关联结构体
        GenerateCompactStructWithReferences(structName, sb, allReferencedTypes, structReferences, processedStructs, 1);
        
        sb.AppendLine("```");
    }
    
    // 递归生成结构体及其引用的结构体
    private void GenerateCompactStructWithReferences(
        string structName, 
        StringBuilder sb, 
        HashSet<string> allReferencedTypes,
        Dictionary<string, HashSet<string>> structReferences,
        HashSet<string> processedStructs,
        int level)
    {
        // 避免重复处理和无限递归
        if (processedStructs.Contains(structName) || level > 10)
        {
            return;
        }
        
        processedStructs.Add(structName);
        
        if (!protocolStructs.ContainsKey(structName))
        {
            return;
        }
        
        string indent = new string(' ', 4 * level);
        var fields = protocolStructs[structName];
        
        // 处理该结构体的每个字段
        foreach (var field in fields)
        {
            bool isOptional = field.Type.EndsWith("*");
            string type = isOptional ? field.Type.TrimEnd('*') : field.Type;
            
            // 将描述内容放在括号内
            string description = field.Description;
            if (!string.IsNullOrEmpty(description))
            {
                // 输出字段名和包含描述的类型信息
                sb.AppendLine($"{indent}{field.Name} ({type}, {(isOptional ? "可选" : "必填")}, {description})");
                
                // 检查该字段是否引用了其他结构体，如果是，则缩进显示该结构体
                string baseType = GetBaseType(field.Type);
                if (protocolStructs.ContainsKey(baseType) && includeReferencedStructs && baseType != structName)
                {
                    // 显示引用结构体名称
                    sb.AppendLine($"{indent}    {baseType}:");
                    
                    // 递归处理引用的结构体
                    GenerateCompactStructWithReferences(baseType, sb, allReferencedTypes, structReferences, processedStructs, level + 2);
                }
            }
            else
            {
                // 如果没有描述，只显示字段名和类型信息
                sb.AppendLine($"{indent}{field.Name} ({type}, {(isOptional ? "可选" : "必填")})");
                
                // 检查该字段是否引用了其他结构体
                string baseType = GetBaseType(field.Type);
                if (protocolStructs.ContainsKey(baseType) && includeReferencedStructs && baseType != structName)
                {
                    // 显示引用结构体名称
                    sb.AppendLine($"{indent}    {baseType}:");
                    
                    // 递归处理引用的结构体
                    GenerateCompactStructWithReferences(baseType, sb, allReferencedTypes, structReferences, processedStructs, level + 2);
                }
            }
        }
    }
    
    // 生成可折叠格式文档
    private void GenerateCollapsibleFormatDoc(string structName, StringBuilder sb, HashSet<string> allReferencedTypes, Dictionary<string, HashSet<string>> structReferences)
    {
        sb.AppendLine($"# {structName} 结构体文档");
        sb.AppendLine();
        
        if (!protocolStructs.ContainsKey(structName))
        {
            sb.AppendLine("- **结构体未定义**");
            return;
        }
        
        // 创建一个已处理结构体的集合，避免重复处理
        HashSet<string> processedStructs = new HashSet<string>();
        
        // 添加主结构体
        sb.AppendLine($"- **{structName}**");
        
        // 使用递归方式生成可折叠格式的文档
        GenerateCollapsibleStructWithReferences(structName, sb, allReferencedTypes, structReferences, processedStructs, 1);
    }
    
    // 递归生成可折叠格式的结构体及其引用
    private void GenerateCollapsibleStructWithReferences(
        string structName, 
        StringBuilder sb, 
        HashSet<string> allReferencedTypes,
        Dictionary<string, HashSet<string>> structReferences,
        HashSet<string> processedStructs,
        int level)
    {
        // 避免重复处理和无限递归
        if (processedStructs.Contains(structName) || level > 10 || !protocolStructs.ContainsKey(structName))
        {
            return;
        }
        
        processedStructs.Add(structName);
        
        var fields = protocolStructs[structName];
        
        // 检查是否为空协议
        if (fields.Count == 0)
        {
            sb.AppendLine($"{new string(' ', level * 2)}- *空协议，不包含任何字段*");
            return;
        }
        
        // 处理该结构体的每个字段
        foreach (var field in fields)
        {
            bool isOptional = field.Type.EndsWith("*");
            string type = isOptional ? field.Type.TrimEnd('*') : field.Type;
            string indent = new string(' ', level * 2);
            
            // 将描述内容放在括号内
            if (!string.IsNullOrEmpty(field.Description))
            {
                sb.AppendLine($"{indent}- **{field.Name}** ({type}, {(isOptional ? "可选" : "必填")}, {field.Description})");
            }
            else
            {
                sb.AppendLine($"{indent}- **{field.Name}** ({type}, {(isOptional ? "可选" : "必填")})");
            }
            
            // 检查该字段是否引用了其他结构体
            string baseType = GetBaseType(field.Type);
            if (protocolStructs.ContainsKey(baseType) && includeReferencedStructs && baseType != structName)
            {
                // 显示引用结构体名称
                sb.AppendLine($"{indent}  - **{baseType}**");
                
                // 递归处理引用的结构体
                GenerateCollapsibleStructWithReferences(baseType, sb, allReferencedTypes, structReferences, processedStructs, level + 2);
            }
        }
    }
    
    // 获取字段类型的基本类型（去除数组、字典和可选标记）
    private string GetBaseType(string type)
    {
        string baseType = type;
        if (baseType.EndsWith("*"))
        {
            baseType = baseType.TrimEnd('*');
        }
        
        if (baseType.EndsWith("[]"))
        {
            baseType = baseType.Substring(0, baseType.Length - 2);
        }
        else if (baseType.EndsWith("{}"))
        {
            baseType = baseType.Substring(0, baseType.Length - 2);
        }
        
        return baseType;
    }

    // 根据复选框状态更新选中的格式
    private void UpdateSelectedFormat()
    {
        // 确保当前有一个主选中格式用于预览
        // 优先级：可折叠格式 > 简洁缩进格式 > 原始表格格式
        if (useCollapsibleFormat)
        {
            selectedFormat = OutputFormat.CollapsibleFormat;
        }
        else if (useCompactFormat)
        {
            selectedFormat = OutputFormat.CompactFormat;
        }
        else if (useNormalFormat)
        {
            selectedFormat = OutputFormat.Normal;
        }
        
        // 保存选择状态
        EditorPrefs.SetBool(NormalFormatKey, useNormalFormat);
        EditorPrefs.SetBool(CompactFormatKey, useCompactFormat);
        EditorPrefs.SetBool(CollapsibleFormatKey, useCollapsibleFormat);
        EditorPrefs.SetInt(OutputFormatKey, (int)selectedFormat);
    }

    // 加载单个协议文件
    private void LoadSingleProtocolFile(string filePath)
    {
        try
        {
            // 检查文件是否存在，对于Assets路径特殊处理
            bool fileExists = File.Exists(filePath);
            string fullPath = filePath;
            
            // 如果是Assets相对路径，转换为完整路径
            if (!fileExists && filePath.StartsWith("Assets/"))
            {
                fullPath = Path.Combine(Application.dataPath, filePath.Substring(7));
                fileExists = File.Exists(fullPath);
            }
            
            if (!fileExists)
            {
                Debug.LogError($"文件不存在: {filePath}");
                return;
            }
            
            // 读取文件内容
            string content = File.ReadAllText(fullPath);
            
            // 提取Lua字符串中的JSON数据
            int startIndex = content.IndexOf("[[");
            int endIndex = content.LastIndexOf("]]");
            
            if (startIndex != -1 && endIndex != -1)
            {
                string jsonText = content.Substring(startIndex + 2, endIndex - startIndex - 2).Trim();
                
                // 解析JSON数据以提取结构体定义
                int beforeCount = protocolStructs.Count;
                ParseProtocolStructs(jsonText);
                int afterCount = protocolStructs.Count;
                
                int newStructsCount = afterCount - beforeCount;
                Debug.Log($"从文件 {Path.GetFileName(filePath)} 中加载了 {newStructsCount} 个结构体");
                
                // 设置加载状态
                isLoaded = protocolStructs.Count > 0;
                
                if (showDetailLog)
                {
                    // 输出所有加载的结构体名称
                    StringBuilder sb = new StringBuilder();
                    sb.AppendLine($"已加载的结构体 (总数 {protocolStructs.Count}):");
                    foreach (var structName in protocolStructs.Keys.OrderBy(k => k))
                    {
                        sb.AppendLine($"- {structName}");
                    }
                    Debug.Log(sb.ToString());
                }
            }
            else
            {
                Debug.LogError($"文件格式错误 (无法找到 [[...]]): {filePath}");
                EditorUtility.DisplayDialog("格式错误", $"文件格式错误: {Path.GetFileName(filePath)}\n\n无法找到协议数据 [[...]]，请检查文件格式。", "确定");
                
                // 如果该文件已添加到列表中，从列表中移除
                if (protocolFilePaths.Contains(filePath))
                {
                    protocolFilePaths.Remove(filePath);
                }
            }
        }
        catch (Exception ex)
        {
            Debug.LogError($"加载文件 {filePath} 时出错: {ex.Message}");
            EditorUtility.DisplayDialog("加载错误", $"加载文件 {Path.GetFileName(filePath)} 时出错:\n\n{ex.Message}", "确定");
            
            // 如果该文件已添加到列表中，从列表中移除
            if (protocolFilePaths.Contains(filePath))
            {
                protocolFilePaths.Remove(filePath);
            }
        }
    }

    // 重新加载所有协议文件
    private void ReloadAllProtocolFiles()
    {
        // 清空现有结构体
        protocolStructs.Clear();
        
        // 如果没有文件，则设置加载状态为false
        if (protocolFilePaths.Count == 0)
        {
            isLoaded = false;
            outputDoc = "";
            return;
        }
        
        // 重新加载所有文件
        bool hasError = false;
        for (int i = 0; i < protocolFilePaths.Count; i++)
        {
            try
            {
                string filePath = protocolFilePaths[i];
                if (File.Exists(filePath))
                {
                    string content = File.ReadAllText(filePath);
                    
                    // 提取Lua字符串中的JSON数据
                    int startIndex = content.IndexOf("[[");
                    int endIndex = content.LastIndexOf("]]");
                    
                    if (startIndex != -1 && endIndex != -1)
                    {
                        string jsonText = content.Substring(startIndex + 2, endIndex - startIndex - 2).Trim();
                        
                        // 解析JSON数据以提取结构体定义
                        int beforeCount = protocolStructs.Count;
                        ParseProtocolStructs(jsonText);
                        int afterCount = protocolStructs.Count;
                        
                        int newStructsCount = afterCount - beforeCount;
                        if (showDetailLog)
                        {
                            Debug.Log($"从文件 {Path.GetFileName(filePath)} 中重新加载了 {newStructsCount} 个结构体");
                        }
                    }
                    else
                    {
                        hasError = true;
                        Debug.LogError($"文件格式错误 (无法找到 [[...]]): {filePath}");
                    }
                }
                else
                {
                    hasError = true;
                    Debug.LogError($"文件不存在: {filePath}");
                }
            }
            catch (Exception ex)
            {
                hasError = true;
                Debug.LogError($"重新加载协议文件时出错: {ex.Message}");
            }
        }
        
        // 设置加载状态
        isLoaded = protocolStructs.Count > 0;
        
        // 如果结构体列表为空，则清空输出文档
        if (protocolStructs.Count == 0)
        {
            outputDoc = "";
        }
        // 如果之前有选择的结构体名称，且该结构体仍然存在，则重新生成文档
        else if (!string.IsNullOrEmpty(inputStructName) && protocolStructs.ContainsKey(inputStructName))
        {
            GenerateDoc();
            // 强制刷新UI
            Repaint();
        }
        // 如果之前选择的结构体不再存在，则清空输出文档
        else if (!string.IsNullOrEmpty(inputStructName))
        {
            outputDoc = "";
            inputStructName = ""; // 清空不存在的结构体名称
            EditorPrefs.SetString(SelectedStructNameKey, ""); // 同步到EditorPrefs
        }
        
        if (hasError)
        {
            Debug.LogWarning("部分协议文件加载失败，请检查控制台日志获取详细信息。");
        }
    }

    // 检查文件是否是有效的协议格式
    private bool IsValidProtocolFormat(string filePath)
    {
        try
        {
            // 检查文件是否存在，对于Assets路径特殊处理
            bool fileExists = File.Exists(filePath);
            string fullPath = filePath;
            
            // 如果是Assets相对路径，转换为完整路径
            if (!fileExists && filePath.StartsWith("Assets/"))
            {
                fullPath = Path.Combine(Application.dataPath, filePath.Substring(7));
                fileExists = File.Exists(fullPath);
            }
            
            if (!fileExists)
            {
                Debug.LogError($"文件不存在: {filePath}");
                return false;
            }
            
            // 读取文件内容
            string content = File.ReadAllText(fullPath);
            
            // 提取Lua字符串中的JSON数据
            int startIndex = content.IndexOf("[[");
            int endIndex = content.LastIndexOf("]]");
            
            if (startIndex != -1 && endIndex != -1 && startIndex < endIndex)
            {
                string jsonText = content.Substring(startIndex + 2, endIndex - startIndex - 2).Trim();
                
                // 基本验证：确保内容以{开始，以}结束
                if (jsonText.StartsWith("{") && jsonText.EndsWith("}"))
                {
                    return true;
                }
                else
                {
                    Debug.LogError($"文件 {filePath} 中的JSON格式不正确");
                    return false;
                }
            }
            else
            {
                Debug.LogError($"文件格式错误 (无法找到 [[...]]): {filePath}");
                return false;
            }
        }
        catch (Exception ex)
        {
            Debug.LogError($"验证文件 {filePath} 格式时出错: {ex.Message}");
            return false;
        }
    }

    private class ProtocolField
    {
        public string Name { get; set; }
        public string Type { get; set; }
        public string Description { get; set; }
    }
} 